﻿// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using com.paypal.sdk.profiles;
using com.paypal.sdk.services;
using com.paypal.soap.api;
using InterpriseSuiteEcommerceCommon;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration;

namespace InterpriseSuiteEcommerceGateways
{
    /// <summary>
    /// Summary description for PayPalSupport
    /// </summary>
    public class PayPalExpress
    {
        private CallerServices _Caller = null;
        private string m_strApiUserName = string.Empty;
        private string m_strApiPassword = string.Empty;
        private string m_strApiSignature = string.Empty;
        private string m_strApiCheckoutURL = string.Empty;
        private PaymentActionCodeType m_paymentAction = PaymentActionCodeType.Authorization;
        private bool m_blnUseSandbox = true;

        string merchantpwd64 = string.Empty, merchantsalt64 = string.Empty, merchantiv64 = string.Empty;
        string merchantPassword = string.Empty;

        public PayPalExpress()
        {
            if (AppLogic.IsSupportedAlternateCheckout)
            {
                using (SqlConnection con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (IDataReader reader = DB.GetRSFormat(con, "SELECT CCCGMA.MerchantLogin, SecretHash, MerchantPassword, MerchantPasswordSalt, MerchantPasswordIV, TestMode " +
                                                                     "FROM CustomerCreditCardGatewayMerchantAccount CCCGMA WITH (NOLOCK), EcommerceAppConfig EAC WITH (NOLOCK)" +
                                                                     "WHERE CCCGMA.MerchantLogin = REPLACE(REPLACE(REPLACE(EAC.ConfigValue, CHAR(10), ''), CHAR(13), ''), CHAR(9), '')" +
                                                                     "AND EAC.WebSiteCode = {0} AND EAC.Name = 'PayPalCheckout.MerchantLogin'", DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode)))
                    {
                        if (reader.Read())
                        {
                            m_strApiUserName = DB.RSField(reader, "MerchantLogin");
                            m_strApiSignature = DB.RSField(reader, "SecretHash");
                            merchantpwd64 = DB.RSField(reader, "MerchantPassword");
                            merchantsalt64 = DB.RSField(reader, "MerchantPasswordSalt");
                            merchantiv64 = DB.RSField(reader, "MerchantPasswordIV");
                            m_blnUseSandbox = DB.RSFieldBool(reader, "TestMode");
                        }
                    }
                }

                byte[] merchantpwd = Convert.FromBase64String(merchantpwd64);
                byte[] merchantsalt = Convert.FromBase64String(merchantsalt64);
                byte[] merchantiv = Convert.FromBase64String(merchantiv64);

                merchantPassword = InterpriseHelper.Decryption(merchantpwd, merchantsalt, merchantiv);
                m_strApiPassword = merchantPassword;

                if (!UseSandbox)
                {
                    m_strApiCheckoutURL = AppLogic.AppConfig("PayPalCheckout.ApiCheckoutURL");
                }
                else
                {
                    m_strApiCheckoutURL = AppLogic.AppConfig("PayPalCheckout.SandboxApiCheckoutURL");
                }

                m_paymentAction = PaymentActionCodeType.Authorization;
            }

        }

        static public string ErrorMsg
        {
            get
            {
                if (!AppLogic.IsSupportedAlternateCheckout)
                    return "This version does not support alternate checkout methods.  Please visit <a href='http://www.interprisesuite.com'>http://www.interprisesuite.com</a> for upgrade.";
                else
                    return null;
            }
        }

        public string APIUsername
        {
            get
            {
                return m_strApiUserName;
            }
        }

        public string APIPassword
        {
            get
            {
                return m_strApiPassword;
            }
        }

        public string APISignature
        {
            get
            {
                return m_strApiSignature;
            }
        }

        public string ApiCheckoutUrl
        {
            get
            {
                return m_strApiCheckoutURL;
            }
        }

        public bool UseSandbox
        {
            get
            {
                return m_blnUseSandbox;
            }
        }

        public PaymentActionCodeType PaymentAction
        {
            get
            {
                return m_paymentAction;
            }
        }

        public CallerServices Caller
        {
            get
            {
                if (_Caller == null)
                {
                    // Set up an api caller from web.config
                    _Caller = new CallerServices();
                    _Caller.APIProfile = GetProfileFromConfig();
                }

                return _Caller;
            }
        }

        public IAPIProfile GetProfileFromConfig()
        {
            // Load profile from web.config
            IAPIProfile profile = ProfileFactory.createSignatureAPIProfile();
            profile.APIUsername = APIUsername;
            profile.APIPassword = APIPassword;
            profile.APISignature = APISignature;
            profile.Environment = !UseSandbox ? "live" : "sandbox";
            profile.Subject = string.Empty;
            return profile;
        }

        public GetExpressCheckoutDetailsResponseType GetExpressCheckoutDetails(string token)
        {
            // Create the request object
            var pp_request = new GetExpressCheckoutDetailsRequestType();
            
            pp_request.Token = token;

            return (GetExpressCheckoutDetailsResponseType)Caller.Call("GetExpressCheckoutDetails", pp_request);
        }

        public DoExpressCheckoutPaymentResponseType DoExpressCheckoutPayment(string token, string payerID, string SalesOrderCode, InterpriseShoppingCart cart)
        {
            // Create the request object
            var pp_request = new DoExpressCheckoutPaymentRequestType();

            // Create the request details object
            pp_request.DoExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType()
            {
                Token = token,
                PayerID = payerID,
            };        

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails = new PaymentDetailsType[1];
            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0] = new PaymentDetailsType();

            var currencyCodeType = (CurrencyCodeType)Enum.Parse(typeof(CurrencyCodeType), ResolveCurrencyCode(cart.ThisCustomer.CurrencyCode));

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].OrderTotal = new BasicAmountType()
            {
                Value = cart.GetOrderBalance().ToString(),
                currencyID = currencyCodeType,
            };

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ButtonSource = "InterpriseSoftware_EC";
            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].InvoiceID = SalesOrderCode;

            int itemCount = cart.CartItems.Count;
            var paymentDetailsItem_array = new PaymentDetailsItemType[itemCount];

            for (int ctr = 0; ctr < itemCount; ctr++)
            {
                var cItem = cart.CartItems[ctr];
                var paymentDetailsItem = new PaymentDetailsItemType();
                paymentDetailsItem.Name = HttpUtility.HtmlEncode(cItem.ItemName);
                paymentDetailsItem.Quantity = cItem.m_Quantity.ToString("#");
                paymentDetailsItem.Amount = new BasicAmountType();
                decimal discountAmount = 0;
                if (cart.HasCoupon())
                {
                    if (((string)cart.SalesOrderDataset.CustomerSalesOrderView[0][cart.SalesOrderDataset.CustomerSalesOrderView.CouponDiscountTypeColumn.ColumnName]).ToLowerInvariant() == "percent")
                    {
                        discountAmount = cItem.AssociatedLineItemRow.SalesPriceRate * (cItem.AssociatedLineItemRow.CouponDiscountRate / 100);
                        paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", (cItem.AssociatedLineItemRow.SalesPriceRate - discountAmount));
                    }
                    else
                    {
                        decimal discountedAmount = (cItem.AssociatedLineItemRow.SalesPriceRate * cItem.m_Quantity) - cItem.AssociatedLineItemRow.CouponDiscountRate;
                        decimal itemUnitPrice = discountedAmount / cItem.m_Quantity;
                        paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", itemUnitPrice);
                    }
                }
                else
                {
                    paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", cItem.AssociatedLineItemRow.SalesPriceRate);
                }
                paymentDetailsItem.Amount.currencyID = currencyCodeType;
                paymentDetailsItem_array.SetValue(paymentDetailsItem, ctr);
            }

            decimal itemTotal = 0;
            foreach (var key in paymentDetailsItem_array)
            {
                if (key.Amount != null)
                {
                    itemTotal = itemTotal + (decimal.Parse(key.Amount.Value) * decimal.Parse(key.Quantity));
                }
            }

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ShippingTotal = new BasicAmountType() 
            {
                Value = string.Format("{0:0,0.00}", cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightRate),
                currencyID = currencyCodeType,
            };

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].TaxTotal = new BasicAmountType()
            {
                Value = string.Format("{0:0,0.00}", cart.SalesOrderDataset.CustomerSalesOrderView[0].TaxRate),
                currencyID = currencyCodeType,
            };

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ItemTotal = new BasicAmountType() 
            {
                Value = string.Format("{0:0,0.00}", itemTotal),
                currencyID = currencyCodeType,
            };

            //added this code to handle the scenario wherein the item unit price - discount conflicts with the order total upon submit to PayPal   

            decimal shippingTotal = Convert.ToDecimal(pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ShippingTotal.Value);
            decimal taxTotal = Convert.ToDecimal(pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].TaxTotal.Value);
            decimal orderTotal = Convert.ToDecimal(pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].OrderTotal.Value);
            decimal cartTotal = 0;

            if (shippingTotal > 0 || taxTotal > 0)
            {
                cartTotal = itemTotal + shippingTotal + taxTotal;
            }
            else
            {
                cartTotal = itemTotal;
            }

            if (cartTotal != orderTotal)
            {
                paymentDetailsItem_array = new PaymentDetailsItemType[0];
                pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ItemTotal.Value = "0";
                pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].ShippingTotal.Value = "0";
                pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].TaxTotal.Value = "0";
            }
           
            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].PaymentAction = this.PaymentAction;
            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].PaymentActionSpecified = true;

            pp_request.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0].PaymentDetailsItem = paymentDetailsItem_array;

            return (DoExpressCheckoutPaymentResponseType)Caller.Call("DoExpressCheckoutPayment", pp_request);
        }
        
        public SetExpressCheckoutResponseType SetExpressCheckout(string returnURL, string cancelURL, InterpriseShoppingCart cart)
        {
            // Create the request object
            var pp_request = new SetExpressCheckoutRequestType();

            // Create the request details object
            pp_request.SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType() 
            {
                CancelURL = cancelURL,
                ReturnURL = returnURL,
                ReqConfirmShipping = AppLogic.AppConfig("PayPalCheckout.RequireConfirmedAddress"),
            };

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails = new PaymentDetailsType[1];
            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0] = new PaymentDetailsType();

            var currencyCodeType = (CurrencyCodeType)Enum.Parse(typeof(CurrencyCodeType), ResolveCurrencyCode(cart.ThisCustomer.CurrencyCode));

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].OrderTotal = new BasicAmountType()
            {
                Value = cart.GetOrderBalance().ToString(),
                currencyID = currencyCodeType,
            };

            //added to determine if cart contain item/s that doesnt require shipping
            if (!cart.HasShippableComponents())
            {
                pp_request.SetExpressCheckoutRequestDetails.NoShipping = "1";
            }
            else
            {
                pp_request.SetExpressCheckoutRequestDetails.NoShipping = "0";
                ////added to override paypal address record
                // Create the request address object
                pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress = new AddressType();

                if (Customer.Current.IsNotRegistered)
                {
                    var anonShippingAddress = Address.Get(Customer.Current, AddressTypes.Shipping, cart.FirstItem().m_ShippingAddressID);
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Name = anonShippingAddress.Name;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.AddressID = anonShippingAddress.AddressID;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Street1 = anonShippingAddress.Address1;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CityName = anonShippingAddress.City;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.StateOrProvince = anonShippingAddress.State;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.PostalCode = anonShippingAddress.PostalCode;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CountryName = ResolveAddressCode(anonShippingAddress.Country);
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), ResolveAddressCode(anonShippingAddress.CountryISOCode));
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CountrySpecified = true;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Phone = anonShippingAddress.Phone;
                }
                else
                {
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Name = Customer.Current.PrimaryShippingAddress.Name;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.AddressID = Customer.Current.PrimaryShippingAddress.AddressID;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Street1 = Customer.Current.PrimaryShippingAddress.Address1;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CityName = Customer.Current.PrimaryShippingAddress.City;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.StateOrProvince = Customer.Current.PrimaryShippingAddress.State;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.PostalCode = Customer.Current.PrimaryShippingAddress.PostalCode;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CountryName = ResolveAddressCode(Customer.Current.PrimaryShippingAddress.Country);
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), ResolveAddressCode(Customer.Current.PrimaryShippingAddress.CountryISOCode));
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.CountrySpecified = true;
                    pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShipToAddress.Phone = Customer.Current.PrimaryShippingAddress.Phone;
                }

                pp_request.SetExpressCheckoutRequestDetails.AddressOverride = AppLogic.AppConfig("PayPalCheckout.OverrideAddress");
            }

            //Set the items for the order history in paypal     
            int itemCount = cart.CartItems.Count;
            var paymentDetailsItem_array = new PaymentDetailsItemType[itemCount];

            for (int ctr = 0; ctr < itemCount; ctr++)
            {
                var cItem = cart.CartItems[ctr];
                var paymentDetailsItem = new PaymentDetailsItemType();
                paymentDetailsItem.Name = HttpUtility.HtmlEncode(cItem.ItemName);
                paymentDetailsItem.Quantity = cItem.m_Quantity.ToString("#");
                paymentDetailsItem.Amount = new BasicAmountType();
                decimal discountAmount = 0;
                if (cart.HasCoupon())
                {
                    if (((string)cart.SalesOrderDataset.CustomerSalesOrderView[0][cart.SalesOrderDataset.CustomerSalesOrderView.CouponDiscountTypeColumn.ColumnName]).ToLowerInvariant() == "percent")
                    {
                        discountAmount = cItem.AssociatedLineItemRow.SalesPriceRate * (cItem.AssociatedLineItemRow.CouponDiscountRate / 100);
                        paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", (cItem.AssociatedLineItemRow.SalesPriceRate - discountAmount));
                    }
                    else
                    {
                        decimal discountedAmount = (cItem.AssociatedLineItemRow.SalesPriceRate * cItem.m_Quantity) - cItem.AssociatedLineItemRow.CouponDiscountRate;
                        decimal itemUnitPrice = discountedAmount / cItem.m_Quantity;
                        paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", itemUnitPrice);
                    }
                }
                else
                {
                    paymentDetailsItem.Amount.Value = string.Format("{0:0.00}", cItem.AssociatedLineItemRow.SalesPriceRate);
                }
                paymentDetailsItem.Amount.currencyID = currencyCodeType;
                paymentDetailsItem_array.SetValue(paymentDetailsItem, ctr);
            }

            decimal itemTotal = 0;
            foreach (var key in paymentDetailsItem_array)
            {
                if (key.Amount != null)
                {
                    itemTotal = itemTotal + (decimal.Parse(key.Amount.Value) * decimal.Parse(key.Quantity));
                }
            }

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShippingTotal = new BasicAmountType()
            {
                Value = string.Format("{0:0,0.00}", cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightRate),
                currencyID = currencyCodeType,
            };

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].TaxTotal = new BasicAmountType()
            {
                Value = string.Format("{0:0,0.00}", cart.SalesOrderDataset.CustomerSalesOrderView[0].TaxRate),
                currencyID = currencyCodeType,
            };

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ItemTotal = new BasicAmountType()
            {
                Value = string.Format("{0:0,0.00}", itemTotal),
                currencyID = currencyCodeType,
            };

            //added this code to handle the scenario wherein the item unit price - discount conflicts with the order total upon submit to PayPal   

            decimal shippingTotal = Convert.ToDecimal(pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShippingTotal.Value);
            decimal taxTotal = Convert.ToDecimal(pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].TaxTotal.Value);
            decimal orderTotal = Convert.ToDecimal(pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].OrderTotal.Value);
            decimal cartTotal = 0;

            if (shippingTotal > 0 || taxTotal > 0)
            {
                cartTotal = itemTotal + shippingTotal + taxTotal;
            }
            else
            {
                cartTotal = itemTotal;
            }

            if (cartTotal != orderTotal)
            {
                paymentDetailsItem_array = new PaymentDetailsItemType[0];
                pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ItemTotal.Value = "0";
                pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].ShippingTotal.Value = "0";
                pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].TaxTotal.Value = "0";
            }

            //Set the payment action.
            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].PaymentAction = this.PaymentAction;
            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].PaymentActionSpecified = true;

            pp_request.SetExpressCheckoutRequestDetails.PaymentDetails[0].PaymentDetailsItem = paymentDetailsItem_array;

            return (SetExpressCheckoutResponseType)Caller.Call("SetExpressCheckout", pp_request);
        }

        //Format address value to make compatible with PayPal
        public String ResolveAddressCode(string Country)
        {
            string PayPalAdCode = string.Empty;
            if (Country.Equals("EL"))
            {
                PayPalAdCode = "GR";
            }
            else if (Country.Equals("Korea, Republic of"))
            {
                PayPalAdCode = "South Korea";
            }
            else if (Country.Equals("United States of America"))
            {
                PayPalAdCode = "United States";
            }
            else
                PayPalAdCode = Country;

            return PayPalAdCode;
        }

        //Format currency value to make compatible with PayPal
        public String ResolveCurrencyCode(string CurrencyCode)
        {
            string PayPalCurrencyCode = string.Empty;
            if (CurrencyCode.Equals("EURO"))
            {
                PayPalCurrencyCode = "EUR";
            }
            else
                PayPalCurrencyCode = CurrencyCode;

            return PayPalCurrencyCode;
        }

        /// <summary>
        /// Execute API logic for creating redirect url to paypal.
        /// </summary>
        /// <param name="cart">Shopping Cart.</param>
        /// <returns>Status of API call.</returns>
        public static string CheckoutURL(InterpriseShoppingCart cart)
        {
            String url = String.Empty, result = String.Empty, token = String.Empty;
            String cancelURL = AppLogic.GetStoreHTTPLocation(true) + "shoppingcart.aspx";
            String returnURL = AppLogic.GetStoreHTTPLocation(true) + "paypalecpostback.aspx";

            //Initialize API call
            PayPalExpress pp = new PayPalExpress();
            CallerServices caller = new CallerServices();
            try
            {
                caller.APIProfile = pp.GetProfileFromConfig();
                result = AppLogic.ro_OK;
            }
            catch (Exception)
            {
                if (Customer.Current.ThisCustomerSession["paypalfrom"] == "shoppingcart")
                {
                    result = AppLogic.GetString("shoppingcart.aspx.cs.1", Customer.Current.SkinID, Customer.Current.LocaleSetting);
                }
                else if (Customer.Current.ThisCustomerSession["paypalfrom"] == "checkoutpayment")
                {
                    result = AppLogic.GetString("checkoutpayment.aspx.cs.2", Customer.Current.SkinID, Customer.Current.LocaleSetting);
                }
                else
                {
                    result = AppLogic.GetString("checkout1.aspx.cs.1", Customer.Current.SkinID, Customer.Current.LocaleSetting);
                }
            }

            if (result == AppLogic.ro_OK)
            {
                // Make the API request
                SetExpressCheckoutResponseType resp;
                try
                {
                    resp = pp.SetExpressCheckout(returnURL, cancelURL, cart);
                    if (resp.Ack == AckCodeType.Success || resp.Ack == AckCodeType.SuccessWithWarning)
                    {
                        result = AppLogic.ro_OK;
                        token = resp.Token;
                    }
                    else
                    {
                        result = "There is a problem posting to PayPal Express Checkout. Here are some details about the problem: ";
                        result += String.Format("resp.Ack: {0} | resp.Errors:", resp.Ack);
                        foreach (ErrorType error in resp.Errors)
                        {
                            result += String.Format(" {0}: {1}", error.ErrorCode, error.LongMessage);
                        }
                    }
                }
                catch
                {
                    result = "Failed to start PayPal Express Checkout! Please try another payment method.";
                }
            }

            //Check for response
            if (result == AppLogic.ro_OK)
            {
                // Success - redirect to get payment info from PayPal
                url = pp.ApiCheckoutUrl + token;
            }
            else
            {
                if (Customer.Current.ThisCustomerSession["paypalfrom"] == "shoppingcart")
                {
                    url = "shoppingcart.aspx?ErrorMsg=" + Security.UrlEncode(result);
                }
                else if (Customer.Current.ThisCustomerSession["paypalfrom"] == "checkoutpayment")
                {
                    url = "checkoutpayment.aspx?ErrorMsg=" + Security.UrlEncode(result);
                }
                else
                {
                    url = "checkout1.aspx?ErrorMsg=" + Security.UrlEncode(result);
                }
            }

            return url;
        }
    }
}
